package oop.ex3.filemanager.actions;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

import oop.ex3.messages.FileMessage;
import oop.ex3.messages.MessageInterface;
import oop.ex3.messages.ValidHeaders;
import oop.ex3.messages.exception.InvalidHeaderException;
import oop.ex3.messages.exception.UnexpectedMessageEndException;


import oop.ex3.filemanager.FMContext;
import oop.ex3.filemanager.FileInfo;
import oop.ex3.filemanager.actions.exceptions.InvalidNumOfParamsException;
import oop.ex3.filemanager.actions.exceptions.RecievedError;
import oop.ex3.nameserver.exception.UnexpectedMessageException;
import oop.ex3.sockets.ClientSocket;

public class RemoveFile extends FmAction {
	
	private static final int NUM_OF_PARAMS = 2;
	private static final int FILE_PLACE = 1;

	/**
	 * constructor for remove file object
	 * @param context - FM's context
	 * @param file - file to delete
	 */
	public RemoveFile(FMContext context) {
		super(context);
	}

	/**
	 * removes a file from FM's DB
	 * @param params- commands params array
	 * @throws InvalidNumOfParamsException 
	 * @throws InterruptedException 
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public void run(String[] params) 
	throws InvalidNumOfParamsException, InterruptedException, 
	UnknownHostException, IOException {
		
		try {
			if (params.length != NUM_OF_PARAMS){
				throw new InvalidNumOfParamsException();
			}
			String file = params[FILE_PLACE];
			if (!_context.containsFile(file)){
				System.out.println("It is impossible to delete an absent file");
			}
			else {
				//TODO you need to varify that it works by pointers
				FileInfo fileInfo = _context.removeFile(file);
				
				
//					Object lock = fileInfo.getLock();
				while (fileInfo._numOfUploads.intValue() != 0){
					synchronized(fileInfo){
						try {
							//TODO change this or something
							fileInfo.wait(5000);	
						} catch (Exception e){
							
						}
						
					}	
				}
				
				File realFile = fileInfo.getFile();
				realFile.delete();
				
				//TODO update all servers
				for (InetSocketAddress server: _context.getServersSet()){
					System.out.println((server == null));
					ClientSocket s = new ClientSocket(server);
					try {
						performHandShake(s);
						FileMessage msg = new 
						FileMessage(ValidHeaders.DONTCONTAINFILE, 
								params[FILE_PLACE]);
						s.SendMessage(msg);
						waitForDone(s);
						finishSession(s);
						s.closeClientSocket();
					} catch (UnexpectedMessageEndException e1) {
						finishSession(s);
						s.closeClientSocket();
					} catch (UnexpectedMessageException e1) {
						finishSession(s);
						s.closeClientSocket();
					} catch (RecievedError e1) {
						finishSession(s);
						s.closeClientSocket();
					} catch (InvalidHeaderException e) {
						finishSession(s);
						s.closeClientSocket();
					}
				}
								
				//notify user
				System.out.println("Removing Done");
			}
		
		} finally {
			
		}
	}

}


